Feat/inpaint improve#411
Merged
Merged
Conversation
marcinz606
commented
Jul 7, 2026
Owner
- improve dust removal inpainting quality
- add scratch removal polyline
- fix some bugs related to manual dust removal brush overlay not exactly matching area that was touched up
…stroke tool Replace the quality-limited fills with two patch-copy primitives (identical math on CPU/numba and GPU/WGSL, parity by construction): - Manual heals: Georgiev-style membrane clone — copy a real source patch (grain exactly matched) and blend the seam with a mean-value-coordinates membrane on the boundary difference (solver-free, single compute pass). Clone source is auto-picked at click time by rim-band SSD scoring and stored in the config. The Telea uint8 + synthetic-grain path is deleted. - Auto/IR heals: guarded reflection copy — sample outward from the defect centroid for grain continuity, rotate away from other defects, fall back to the old trimmed mean so the worst case is unchanged. Detection untouched. New Scratch Tool heals elongated defects: click a polyline along the hair/scratch, double-click to commit, Esc cancels (mirrors the lasso). Strokes live in RetouchConfig.manual_heal_strokes; legacy manual_dust_spots still load and convert at pipeline time with deterministic fallback offsets. Placed heals draw as outlines while a retouch tool is active. Tiled export halo now grows with heal radius + source offset (capped 512px), fixing the pre-existing bug where large spots sampled past the fixed 32px halo across tile boundaries.
Membrane clone sampled the source patch and boundary points raw, so a speck inside the source band got copied straight into the healed area. Two-layer fix, mirrored on CPU (numba) and GPU (WGSL): - Clone-sample guard: every cloned sample (source patch, both boundary sides) whose luma pops above its 3x3 luma-median neighbour by 0.06 is a speck — the median-luma pixel is used instead (a real pixel, grain kept). Ceiling: specks wider than ~2px fill the window and pass through. - Source scoring now probes the candidate patch interior (chain + inner ring) and heavily penalizes lumas above the candidate band's median, so dusty patches lose to clean ones upfront — rim-band SSD alone could not see interior dust.
…apsule The manual heal replaced the entire brushed capsule with shifted source texture, which read as cloning a bigger area than selected and could still drag a large speck along. The brush is now a search area: - Destination dust gate (CPU + WGSL): a brushed pixel is healed only when its luma exceeds the membrane-predicted clean value (smoothstep 0.04-0.12, encoded domain). Clean pixels inside the brush stay untouched. - The directly-cloned source sample upgrades from a 3x3 to a 5x5 luma-median guard, catching specks up to ~4px that slipped through before; boundary samples keep the cheaper 3x3.
The pipeline treated brush size as a radius while the overlay cursor draws size/(2*preview_render_size) — half of it — so the healed area was 2x the visible circle. Brush size is now a diameter everywhere: pipeline radius is size/2 * scale_factor, matching overlay._brush_screen_radius 1:1 at any zoom and resolution (the source-offset scoring radius in the controller follows the same convention). Locked in by tests: a dust strip crossing the brush is healed strictly inside the brush circle (max changed-pixel distance <= radius, strip untouched outside), and the pipeline radius fraction equals the cursor fraction exactly.
Pure formatting (AST-identical): line joins/splits and blank-line removal from a ruff format pass; no behavior change.
Same behaviour as double-click: Enter commits an in-progress scratch stroke or closes a lasso polygon (only when it has >= 3 vertices — fewer keeps the draw alive instead of wiping it). The overlay now takes click focus so its widget-context shortcuts (Esc cancel, Enter finish) actually fire after the user clicks the canvas; without a focus policy they never could.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.